#include "controller.h"
#include "core.h"
#include "core_wl.h"

Controller *Controller::getInstance()
{
    static Controller c;
    return &c;
}

void Controller::setPropertyOfSelectWid(uint qId, bool isfullscreen, bool isWindow, QString screen, uint id, QRect rect, double scale)
{
    if (!(m_info.waylandDectected() && !m_info.isHWWayland() && (m_info.windowManager() == DesktopInfo::UKUI)))
    {
        Core::getInstance()->setPropertyOfSelectWid(qId, isfullscreen, isWindow, screen, id, rect, scale);
    }
    else
    {
        Core_wl::getInstance()->setPropertyOfSelectWid(qId, isfullscreen, isWindow, screen, id, rect, scale);
    }
}

void Controller::startRecord( uint winId, const QRect &rect)

{
    qDebug()<<"Controller::startRecord 开始录制时的捕获窗口 "<< m_captureWindow;

    if(m_settingWid->m_isInitComplete){ //第一次初始化完成时

        if (!(m_info.waylandDectected() && !m_info.isHWWayland() && (m_info.windowManager() == DesktopInfo::UKUI)))
        {
            Core::getInstance()->setSavePath(m_settingWid->m_saveDirectory->toolTip());
            Core::getInstance()->setSaveFormat(m_settingWid->m_saveFormat->currentText());
            Core::getInstance()->setResolution(m_settingWid->m_resolution->currentIndex());
            Core::getInstance()->setFrameRate(m_settingWid->m_frameRate->currentText());
            Core::getInstance()->setMicrophone(m_settingWid->m_microphone->currentText());
        }else{
            Core_wl::getInstance()->setSavePath(m_settingWid->m_saveDirectory->toolTip());
            Core_wl::getInstance()->setSaveFormat(m_settingWid->m_saveFormat->currentText());
            Core_wl::getInstance()->setResolution(m_settingWid->m_resolution->currentIndex());
            Core_wl::getInstance()->setFrameRate(m_settingWid->m_frameRate->currentText());
            Core_wl::getInstance()->setMicrophone(m_settingWid->m_microphone->currentText());
        }

        m_settingWid->m_isInitComplete = false;
    }

    //内存检测
    m_savePath = m_settingWid->m_saveDirectory->toolTip();
    checkSavePath();
    bool spaceLow = diskSpaceDetection();
    if(spaceLow){
        qDebug()<<"Controller::startRecord  存储空间不足 返回";
        ScreencapSaver().saveInfoNotification(m_completePath, spaceLow);
        m_diskSpaceLow = false;
        Global::recordStatus = false;
        captureExit(m_qId);
        return;
    }
    qDebug()<<"Controller::startRecord  开始录制";
    m_spaceDetectionTimer->start(1000);

    //开始录制
    m_recordingRect = rect;
    m_statusBar->setQId(m_qId);
    m_statusBar->setRecordingStart();           //录制时间开始
    m_statusBar->setRecordingWid(rect, winId);  //窗口位置调整
    m_statusBar->setFixedWidth(278);
    if(m_micList.count() != 0){
        m_statusBar->openMicIcon(Global::isOpenMic);
    }else{
        m_statusBar->micIconGrayout(false);
    }
    m_usingMicName = ConfigHandler().getMicrophone();
    m_statusBar->show();

    //录制开始 设置的值不可以修改
    emit sigStartRecording();

    if (!(m_info.waylandDectected() && !m_info.isHWWayland() && (m_info.windowManager() == DesktopInfo::UKUI)))
    {
        Core::getInstance()->startRecord(winId, rect);
    }
    else
    {
        uint sourceType = (winId == 0) ? 1 : 2; // 1:区域录制；2：窗口录制
        uint mousecursorMode = Global::isShowCursor ? 2 : 1;  // 是否记录鼠标
        Core_wl::getInstance()->slot_startScreenCast(sourceType, mousecursorMode);
    }

    if (m_dbus_interface->isValid()) {
        if (Global::recordStatus) {
            QDBusMessage reply = m_dbus_interface->call(QDBus::Block, "Inhibit", "kylin-screencap", (quint32)0, "Screen recording", (quint32)8);
            m_inhibit_value = reply.arguments().takeFirst().toUInt();
        } else {
            m_dbus_interface->call("Uninhibit", m_inhibit_value);
        }
    }
}

void Controller::stopRecord(uint qId)
{
    if (!(m_info.waylandDectected() && !m_info.isHWWayland() && (m_info.windowManager() == DesktopInfo::UKUI)))
    {
        Core::getInstance()->stopRecord(m_completePath);
    }
    else
    {
        Core_wl::getInstance()->slot_stopScreenCast();
    }
    emit sigStopRecording();

    //信息提示+完成后动作 停止检测 变量赋值
    bool ok = ScreencapSaver().saveInfoNotification(m_completePath, m_diskSpaceLow);
    if(ok){
        captureTaken(qId , m_completePath);
    }else{
        captureFailed(qId);
    }

    m_spaceDetectionTimer->stop();
    m_diskSpaceLow = false;
    Global::recordStatus = false;
    cameraRectLast = QRect();
    m_dbus_interface->call("Uninhibit", m_inhibit_value);
}

void Controller::pauseRecord()
{
    if (!(m_info.waylandDectected() && !m_info.isHWWayland() && (m_info.windowManager() == DesktopInfo::UKUI)))
    {
        Core::getInstance()->pauseRecord();
    }else{

    }
}

void Controller::contineRecord()
{
    if (!(m_info.waylandDectected() && !m_info.isHWWayland() && (m_info.windowManager() == DesktopInfo::UKUI)))
    {
        Core::getInstance()->contineRecord();
    }else{

    }
}

void Controller::openMicrophone()
{
    if (!(m_info.waylandDectected() && !m_info.isHWWayland() && (m_info.windowManager() == DesktopInfo::UKUI)))
    {
        Core::getInstance()->openMicrophone();
    }else{
        Core_wl::getInstance()->openMicrophone();
    }
}

void Controller::closeMicrophone()
{
    if (!(m_info.waylandDectected() && !m_info.isHWWayland() && (m_info.windowManager() == DesktopInfo::UKUI)))
    {
        Core::getInstance()->closeMicrophone();
    }else{
        Core_wl::getInstance()->closeMicrophone();
    }
}

Controller::Controller(): m_captureWindow(nullptr)
{
    qApp->setQuitOnLastWindowClosed(false);     //用于设置应用程序在最后一个窗口关闭时不退出
    isManagerStart = false;
    enableTrayIcon();
    m_settingWid = new SettingWidget();

    m_leadWid = new LeadWidget();
    m_leadWid->hide();

    m_statusBar = new StatusBar();
    connect(Core::getInstance(), &Core::updateVolume, m_statusBar, &StatusBar::slotUpdateVolume);
    connect(Core_wl::getInstance(), &Core_wl::updateVolume, m_statusBar, &StatusBar::slotUpdateVolume);

    connect(m_statusBar, &StatusBar::sigCloseRec, this, &Controller::slotCloseRec);

    m_spaceDetectionTimer = new QTimer();
    connect(m_spaceDetectionTimer, &QTimer::timeout, this, &Controller::diskSpaceDetection);
    m_micDeviceListTimer = new QTimer();
    connect(m_micDeviceListTimer, &QTimer::timeout, this, &Controller::micDeviceListDetection);
    m_micDeviceListTimer->start(1000);

    initConnect();
    initShortcut();
    initMicDevices();
    initDBus();
    slotTrayIconActivated();

    kdk_dia_upload_program_startup();

    qDebug()<<"controllor 初始化完成";
}

Controller::~Controller()
{
    if(Global::recordStatus){
        m_statusBar->slotStopRecAndSave();
    }
    kdk_dia_upload_program_exit();
    removeShortcut();
}

void Controller::initConnect()
{
    if (!(m_info.waylandDectected() && !m_info.isHWWayland() && (m_info.windowManager() == DesktopInfo::UKUI)))
    {
        connect(m_settingWid, &SettingWidget::sigSavePathChanged,
                Core::getInstance(), &Core::setSavePath);
        connect(m_settingWid, &SettingWidget::sigSaveFormatChanged,
                Core::getInstance(), &Core::setSaveFormat);
        connect(m_settingWid, &SettingWidget::sigResolutionChanged,
                Core::getInstance(), &Core::setResolution);
        connect(m_settingWid, &SettingWidget::sigFrameRateChanged,
                Core::getInstance(), &Core::setFrameRate);
        connect(m_settingWid, &SettingWidget::sigMicrophoneChanged,
                Core::getInstance(), &Core::setMicrophone);
    }else{
        connect(m_settingWid, &SettingWidget::sigSavePathChanged,
                Core_wl::getInstance(), &Core_wl::setSavePath);
        connect(m_settingWid, &SettingWidget::sigSaveFormatChanged,
                Core_wl::getInstance(), &Core_wl::setSaveFormat);
        connect(m_settingWid, &SettingWidget::sigResolutionChanged,
                Core_wl::getInstance(), &Core_wl::setResolution);
        connect(m_settingWid, &SettingWidget::sigFrameRateChanged,
                Core_wl::getInstance(), &Core_wl::setFrameRate);
        connect(m_settingWid, &SettingWidget::sigMicrophoneChanged,
                Core_wl::getInstance(), &Core_wl::setMicrophone);
    }


    connect(this, &Controller::sigStartRecording,
            m_settingWid, &SettingWidget::slotStarRecording);
    connect(this, &Controller::sigStopRecording,
            m_settingWid, &SettingWidget::slotStopRecording);

    connect(this, &Controller::captureTaken,
            this, &Controller::handleCaptureTaken);
    connect(this, &Controller::captureFailed,
            this, &Controller::handleCaptureFailed);

    connect(m_settingWid, &SettingWidget::sigShortcutChanged,
            this, &Controller::unsetShortcut);
    connect(m_settingWid, &SettingWidget::sigCameraRecord,
            this,&Controller::slotCameraRecordToggled);
}

void Controller::initDBus()
{
    m_dbus_interface = new QDBusInterface("org.gnome.SessionManager",
                                         "/org/gnome/SessionManager",
                                         "org.gnome.SessionManager",
                                         QDBusConnection::sessionBus());
    m_dbus_media = new QDBusInterface("org.ukui.media",
                                         "/org/ukui/media",
                                         "org.ukui.media",
                                         QDBusConnection::sessionBus());

    //插拔耳机的3.0信号,考虑到音乐和影音在拔出时发此信号DbusSingleTest,对于录音要停止(两个都不可以注释,否则会出现卡死)
    QDBusConnection::sessionBus().connect(QString(), QString("/"), "org.ukui.media", "DbusSignalRecorder", this,
                                          SLOT(inputDevice_get(QString)));
    QDBusConnection::sessionBus().connect(QString(), QString("/"), "org.ukui.media", "DbusSingleTest", this,
                                          SLOT(inputDevice_get(QString)));
    //插拔输入设备的信号3.1的聲音
    QDBusConnection::sessionBus().connect(QString(), QString("/"), "org.ukui.media", "sourcePortChanged", this,
                                          SLOT(inputDevice_get(QString)));
    //设备静音状态改变
    QDBusConnection::sessionBus().connect(QString(), QString("/org/ukui/media"), "org.ukui.media", "updateSourceMute",
                                          this, SLOT(inputDevice_mute(bool)));

}

void Controller::initShortcut()
{
    m_shortcutCustom = new GlobalKey( this );
    m_shortcutStart = new GlobalKey( this );
    m_shortcutPause = new GlobalKey( this );
    m_shortcutFull = new GlobalKey( this );
    m_shortcutWin = new GlobalKey( this );
    m_shortcutOpenMic = new GlobalKey( this );

    connect( m_shortcutCustom, &GlobalKey::sigKeyTriggered, this, &Controller::slotCustom);
    connect( m_shortcutStart, &GlobalKey::sigKeyTriggered, this, &Controller::slotStart);
    connect( m_shortcutPause, &GlobalKey::sigKeyTriggered, this, &Controller::slotPause);
    connect( m_shortcutFull, &GlobalKey::sigKeyTriggered, this, &Controller::slotFull);
    connect( m_shortcutWin, &GlobalKey::sigKeyTriggered, this, &Controller::slotWin);
    connect( m_shortcutOpenMic, &GlobalKey::sigKeyTriggered, this, &Controller::slotOpenMic);

    QList<QKeySequence> shortcutInvoke =  parseKeySequence(ConfigHandler().getShortcut(ShortcutRec::Invoke));
    m_shortcutCustom->RegisterKey("Invoke",shortcutInvoke);

    QList<QKeySequence> shortcutStart =  parseKeySequence(ConfigHandler().getShortcut(ShortcutRec::Start));
    QList<QKeySequence> shortcutPause =  parseKeySequence(ConfigHandler().getShortcut(ShortcutRec::Pause));
    QList<QKeySequence> shortcutFull =  parseKeySequence(ConfigHandler().getShortcut(ShortcutRec::Full));
    QList<QKeySequence> shortcutWin =  parseKeySequence(ConfigHandler().getShortcut(ShortcutRec::Win));
    QList<QKeySequence> shortcutOpenMic =  parseKeySequence(ConfigHandler().getShortcut(ShortcutRec::OpenMic));
    m_shortcutStart->RegisterKey("Start",shortcutStart);
    m_shortcutPause->RegisterKey("Pause",shortcutPause);
    m_shortcutFull->RegisterKey("Full",shortcutFull);
    m_shortcutWin->RegisterKey("Win",shortcutWin);
    m_shortcutOpenMic->RegisterKey("OpenMic",shortcutOpenMic);
}

QList<QKeySequence> Controller::parseKeySequence(const QString &keySequenceStr)
{
    QList<QKeySequence> keySequences;
        QKeySequence keySequence(keySequenceStr);
        if (!keySequence.isEmpty()) {
            keySequences.append(keySequence);
        }
        return keySequences;
}

void Controller::removeShortcut()
{
    qDebug()<<"Controller::removeShortcut()";
    m_shortcutCustom->UnregisterKey();
    m_shortcutStart->UnregisterKey();
    m_shortcutPause->UnregisterKey();
    m_shortcutFull->UnregisterKey();
    m_shortcutWin->UnregisterKey();
    m_shortcutOpenMic->UnregisterKey();
}

void Controller::checkSavePath()
{
    m_savePath = m_settingWid->m_saveDirectory->toolTip();
    QFileInfo fileInfo(m_savePath);
    if(!fileInfo.exists()){
        qDebug() << "保存路径不存在：" << m_savePath;

        QString defaultLocation = QStandardPaths::writableLocation(QStandardPaths::MoviesLocation);
        QDir dir(defaultLocation);
        QFileInfo info(defaultLocation);
        if(dir.exists() && info.isWritable())
        {
            if (!(m_info.waylandDectected() && !m_info.isHWWayland() && (m_info.windowManager() == DesktopInfo::UKUI)))
            {
                Core::getInstance()->setSavePath(defaultLocation);
            }else{
                Core_wl::getInstance()->setSavePath(defaultLocation);
            }
            m_settingWid->setSavePath(defaultLocation);
            m_savePath = m_settingWid->m_saveDirectory->toolTip();
            qDebug() << "新保存路径：" << m_savePath;
        }else{
            qDebug()<<"不可以写或不存在";
        }
    }
}

void Controller::requestCapture(const CaptureRequest &request)
{
    if(Global::recordStatus){
        qDebug()<<"Controller::requestCapture  之前的录制还未完成，正在录制中 ";
        return;
    }

    uint id = request.id();
    m_requestMap.insert(id, request);
    qDebug()<<"Controller::requestCapture 请求的 mode 和id" <<request.captureMode() <<request.id() ;
    bool enable = ConfigHandler().getKylinscreencap();

    switch (request.captureMode()) {
    case CaptureRequest::FULLSCREEN_MODE:
        if (enable) {
            this->startFullscreenCapture(id);
        } else {
            disableScreencap();
        }
        break;
    case CaptureRequest::SCREEN_MODE:
        if (enable) {
            int &&number = request.data().toInt();
            this->startScreenGrab(id, number);
        } else {
            disableScreencap();
        }
        break;
    case CaptureRequest::GRAPHICAL_MODE:
        if (enable) {
            isManagerStart = false;
            this->startVisualCapture(id);
        } else {
            disableScreencap();
        }
        break;
    case CaptureRequest::OSMANAGER_MODE:
        if (enable) {
            isManagerStart = true;
            this->startVisualCapture(id);
        } else {
            disableScreencap();
        }
        break;
    default:
        emit captureFailed(id);
        break;
    }
}

void Controller::enableTrayIcon()
{
    if (m_trayIcon) {
        return;
    }

    //系统托盘
    m_trayIcon = new TrayIcon();
    m_trayIcon->show();
    connect(m_trayIcon, &TrayIcon::activated, this, &Controller::slotTrayIconActivated);
    connect(m_trayIcon, &TrayIcon::sigTrayCloseRec, this, &Controller::slotTrayStopRecAndSave);
}

void Controller::disableTrayIcon()
{
    if (m_trayIcon) {
        m_trayIcon->deleteLater();
    }
//    ConfigHandler().setDisabledTrayIcon(true);
}

void Controller::disableScreencap()
{
    ScreencapSaver().sendMessage(tr("Unable to use kylin-screencap"));
}

void Controller::inputDevice_get(QString str)
{
    qDebug()<<"Controller::inputDevice_get  输入设备拔插 输入str="<<str;

    m_micList.clear();
    Core::getInstance()->getMicDevices(m_micList,"monitor",true);

    //录制中（点击开始后的录制中）  选择了麦克风  拔掉的是当前麦克风
    if(Global::recordStatus && m_statusBar->isVisible()){
        changedButNoModify = true;
        QString mic = ConfigHandler().getMicrophone();
        if(mic != m_NoMic && !m_micList.contains(mic)){
            m_statusBar->slotStopRecAndSave();
            m_settingWid->micDevicesChanged(m_micList);
            QString tips = tr("Detected that you have unplugged the microphone and cannot continue recording. We have ended recording for you and saved it");
            ScreencapSaver().sendMessage(tips);
            qDebug()<<"提示 ：检测到您已拔掉麦克风，无法继续录制，已为您结束录制并保存" ;
        }
    }else{
        m_settingWid->micDevicesChanged(m_micList);

        //无麦克风-工具栏麦克选项禁用
        if(m_micList.count() == 0){
            m_captureWindow->updateMicOption(false);
        }else {
            m_captureWindow->updateMicOption(true);
        }
    }
    statusMicIcon();
}

void Controller::inputDevice_mute(bool str)
{
    qDebug()<<"Controller::inputDevice_mute  输入:"<< str ;
    //有输入设备，输入设备 = 录音选择的麦克
    QString systemDevice;
    QDBusReply<QString> reply = m_dbus_media->call("getDefaultInputDevice" );
    if (reply.isValid()) {
        systemDevice = reply.value();
    } else {
        qDebug() << "Failed to call " << "getDefaultInputDevice" << ":" << reply.error().message();
    }
    systemDevice = reply.value();
    QString usingMicDevice = Core::getInstance()->getUsingMicDevices();

    if(m_micList.count() != 0 && systemDevice == usingMicDevice){
        m_statusBar->openMicIcon(!str);
    }
}

void Controller::slotTrayIconActivated()
{
    //数据埋点 - 托盘点击事件
    KTrackData *node = kdk_dia_data_init(KEVENTSOURCE_DESKTOP, KEVENT_CLICK);
    kdk_dia_upload_default(node, "start-GUI-record-from-trayIcon", "Controller");
    kdk_dia_data_free(node);

    isManagerStart = false;

    if(m_captureWindow){
        if(m_captureWindow->isVisible()){
            return;
        }
    }
    if(m_statusBar->isVisible()){
        return;
    }
    startVisualCapture();
}

void Controller::slotTrayStopRecAndSave()
{
    if(Global::recordStatus){
        m_statusBar->slotStopRecAndSave();
    }
}

void Controller::openSettingWid()
{
    checkSavePath();
    if(! m_settingWid->isVisible()){
        //每次显示前需要重新去除标题栏和设置毛玻璃
        //X11窗口装饰与毛玻璃
        MotifWmHints hints1;
        hints1.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS;
        hints1.functions = MWM_FUNC_ALL;
        hints1.decorations = MWM_DECOR_BORDER;
        m_settingWid->setAttribute(Qt::WA_TranslucentBackground, true);
        XAtomHelper::getInstance()->setWindowMotifHint(m_settingWid->winId(), hints1);
        KWindowEffects::enableBlurBehind(m_settingWid->winId(), true);

        if (m_settingWid->m_isMaximized) {
            m_settingWid->showMaximized();
        }else{
            m_settingWid->show();
        }
    }else{
        m_settingWid->activateWindow();
    }
}

void Controller::initMicDevices()
{
    if (!(m_info.waylandDectected() && !m_info.isHWWayland() && (m_info.windowManager() == DesktopInfo::UKUI)))
    {
        m_micList.clear();
        Core::getInstance()->getMicDevices(m_micList,"monitor",true);
        if(m_settingWid && m_statusBar){
            m_settingWid->iniMicDevices(m_micList);
            if(m_micList.count() == 0){
                m_statusBar->micIconGrayout(false);
            }else{
                QString name = m_settingWid->m_microphone->currentText();
                Core::getInstance()->levelMeterStart(name);
            }
        }
    }else{
        Core_wl::getInstance()->getMicDevices(m_micList,"monitor");
        if(m_settingWid){
            m_settingWid->iniMicDevices(m_micList);
            QString name = m_settingWid->m_microphone->currentText();
            Core_wl::getInstance()->levelMeterStart(name);
        }
    }
}

void Controller::getAllMicDevicesName(QStringList &list)
{
    Core::getInstance()->getMicDevices(list,"monitor",true);
}

void Controller::diskSpaceLow()
{
    if(Global::recordStatus){
        m_statusBar->slotStopRecAndSave();
    }
}

void Controller::startVisualCapture(const uint id, const QString &forcedSavePath)
{
    //数据埋点 - 开启GUI录制
    KTrackData *node = kdk_dia_data_init(KEVENTSOURCE_DESKTOP, KEVENT_CLICK);
    kdk_dia_upload_default(node, "start-GUI-record", "Controller");
    kdk_dia_data_free(node);

    qDebug()<<"startVisualCapture 开始视图捕获 "<< m_captureWindow;
    bool enable = ConfigHandler().getKylinscreencap();
//    if (!m_captureWindow) {
        //关闭模态窗口
        if(enable){
            qDebug()<<"startVisualCapture enable = "<< enable;

            if(m_leadWid){
                QRect screenGeometry = QGuiApplication::primaryScreen()->geometry();
                double scale = QGuiApplication::primaryScreen()->devicePixelRatio();
                m_leadWid->move(8 / scale, (screenGeometry.height() - 68 - 136) / scale);
                m_leadWid->show();
            }

            QWidget *modalWidget = nullptr;
            do {
                modalWidget = qApp->activeModalWidget();
                if (modalWidget) {
                    modalWidget->close();
                    modalWidget->deleteLater();
                }
            } while (modalWidget);
            m_captureWindow = new CaptureWidget(id, forcedSavePath);

            //无麦克风-工具栏麦克选项禁用
            if(m_micList.count() == 0){
                m_captureWindow->updateMicOption(false);
            }else {
                m_captureWindow->updateMicOption(true);
            }

            connect(m_captureWindow, &CaptureWidget::captureExit,
                    this, &Controller::captureExit);
            Global::recordStatus = true;
        } else {
            disconnect(m_captureWindow, &CaptureWidget::captureExit,
                       this, &Controller::captureExit);
            disableScreencap();
        }

        if (!(m_info.waylandDectected() && !m_info.isHWWayland() && (m_info.windowManager() == DesktopInfo::UKUI)))
        {
            m_captureWindow->showFullScreen();
        }
//    }else {
//        emit captureFailed(id);
//    }
}

void Controller::startFullscreenCapture(const uint qId)
{
    //数据埋点 - 开启全屏录制
    KTrackData *node = kdk_dia_data_init(KEVENTSOURCE_DESKTOP, KEVENT_CLICK);
    kdk_dia_upload_default(node, "start-fullscreen-record", "Controller");
    kdk_dia_data_free(node);

    qDebug()<<"Controller::startFullscreenCapture 开始全屏录制";
    //获取桌面几何信息
    bool ok = true;
    QPixmap p(ScreenGrabber().grabEntireDesktop(ok));
    auto screenNumber = QApplication::desktop()->screenNumber();
    QScreen *screen = QApplication::screens()[screenNumber];
    double scale = screen->devicePixelRatio();
    QRect full_Rect = p.rect();
    full_Rect.setX(full_Rect.x()/scale);
    full_Rect.setY(full_Rect.y()/scale);
    full_Rect.setWidth(full_Rect.width()/scale);
    full_Rect.setHeight(full_Rect.height()/scale);

    //设置参数、开始录制
    Global::recordStatus = true;
    initCameraRecorder(ConfigHandler().getCameraRecord(), QRect(),full_Rect);
    setPropertyOfSelectWid(qId, true, false, "", 0, full_Rect, scale);
    startRecord(0, full_Rect);
}

void Controller::startScreenGrab(const uint qId, const int screenNumber)
{
    //数据埋点 - 开启窗口录制
    KTrackData *node = kdk_dia_data_init(KEVENTSOURCE_DESKTOP, KEVENT_CLICK);
    kdk_dia_upload_default(node, "start-window-record", "Controller");
    kdk_dia_data_free(node);

    qDebug()<<"Controller::startScreenGrab 开始窗口录制";
    //获取窗口在屏幕显示上的图片大小(包含任务栏)
    bool ok = true;
    int n = screenNumber;

    if (n < 0) {
        QPoint globalCursorPos = QCursor::pos();
        n = qApp->desktop()->screenNumber(globalCursorPos);
    }
    QPixmap p(ScreenGrabber().grabScreen(n, ok));
    //设置录制的位置和大小
    auto screenNumber1 = QApplication::desktop()->screenNumber();
    QScreen *screen = QApplication::screens()[screenNumber1];
    double scale = screen->devicePixelRatio();

    uint activeWindowId = KWindowSystem::activeWindow();
    KWindowInfo windowInfo(activeWindowId, NET::WMFrameExtents | NET::WMGeometry);
    QRect Win_rect = windowInfo.frameGeometry();

    //窗口不是完整显示在界面的情况 以及 lefttop不在(0,0)点 的处理
    Win_rect.setX(Win_rect.x()/scale);
    Win_rect.setY(Win_rect.y()/scale);
    bool leftBorder = Win_rect.left()<0 ? true: false;
    bool topBorder = Win_rect.top()<0 ? true: false;
    bool rightBorder = Win_rect.right()<0 ? true: false;
    bool bottomBorder = Win_rect.bottom()<0 ? true: false;

    if( leftBorder && rightBorder ){
        Win_rect.setRight(Win_rect.y() + p.rect().width());
    }
    if( topBorder && bottomBorder ){
        Win_rect.setBottom(Win_rect.x() + p.rect().height());
    }
    if( leftBorder ){
        Win_rect.setLeft(0);
    }

    if( topBorder ){
        Win_rect.setTop(0);
    }
    Win_rect.setWidth(p.rect().width()/scale);
    Win_rect.setHeight(p.rect().height()/scale);    //获取的图片有乘以缩放率

    //传递参数、开始录制
    Global::recordStatus = true;
    setPropertyOfSelectWid(qId, false, true, "", activeWindowId, Win_rect, scale);
    startRecord(activeWindowId, Win_rect);
}

bool Controller::diskSpaceDetection()
{
    bool bfileExit = true;
    bool bResult = ScreencapSaver().diskSpaceDetection(m_savePath, m_diskSpaceLow, bfileExit);
    if (!bfileExit)
    {
        m_spaceDetectionTimer->stop();
        if(Global::recordStatus){
            m_statusBar->slotStopRecAndSave();
        }

        checkSavePath();
        QMessageBox mes;
        mes.warning(nullptr, tr("error"), tr("The save path does not exist，stop record"));
    }

    return bResult;
}

void Controller::micDeviceListDetection()
{
    QStringList preList = m_micList;
    m_micList.clear();
    Core::getInstance()->getMicDevices(m_micList,"monitor",true);

    if (preList != m_micList){  //mic设备列表改变
        qDebug()<<"Controller::micDeviceListDetection() mic设备列表改变";
        if(Global::recordStatus){
            changedButNoModify = true;
        }else {
            m_settingWid->micDevicesChanged(m_micList);
        }
        //修改图标禁用状态
        statusMicIcon();
    }
    if(!Global::recordStatus && changedButNoModify){
        changedButNoModify = false;
        m_settingWid->micDevicesChanged(m_micList);
        //无麦克风-工具栏麦克选项禁用
        if(m_micList.count() == 0){
            m_captureWindow->updateMicOption(false);
        }else {
            m_captureWindow->updateMicOption(true);
        }
    }
}

void Controller::statusMicIcon()
{
    if(m_micList.count() == 0){
        m_statusBar->micIconGrayout(false);
    }else {
        m_statusBar->micIconGrayout(true);
    }
}

void Controller::handleCaptureTaken(uint id, QString completePath)
{
    qDebug()<<"Controller::handleCaptureTaken 录屏捕获成功 ";
    m_requestMap.remove(id);

    if (ConfigHandler().getCloseAfterScreencap()) {
        QApplication::quit();
    }
}

void Controller::handleCaptureFailed(uint id)
{
    qDebug()<<"Controller::handleCaptureFailed 录屏捕获失败 ";
    m_requestMap.remove(id);

    if (ConfigHandler().getCloseAfterScreencap()) {
        QApplication::quit();
    }
}

void Controller::unsetShortcut(ShortcutRec type, QString ShortcutText)
{
    qDebug()<<"Controller::unsetShortcut 重置快捷键 ShortcutText="<<ShortcutText  ;

    QList<QKeySequence> keySequences =  parseKeySequence(ShortcutText);
    switch (type) {
    case ShortcutRec::Invoke:
        m_shortcutCustom->UnregisterKey();
        m_shortcutCustom->RegisterKey("Invoke",keySequences);
        break;
    case ShortcutRec::Start:
        m_shortcutStart->UnregisterKey();
        m_shortcutStart->RegisterKey("Start",keySequences);
        break;
    case ShortcutRec::Pause:
        m_shortcutPause->UnregisterKey();
        m_shortcutPause->RegisterKey("Pause",keySequences);
        break;
    case ShortcutRec::Full:
        m_shortcutFull->UnregisterKey();
        m_shortcutFull->RegisterKey("Full",keySequences);
        break;
    case ShortcutRec::Win:
        m_shortcutWin->UnregisterKey();
        m_shortcutWin->RegisterKey("Win",keySequences);
        break;
    case ShortcutRec::OpenMic:
        m_shortcutOpenMic->UnregisterKey();
        m_shortcutOpenMic->RegisterKey("OpenMic",keySequences);
        break;
    default:
        break;
    }
}

void Controller::slotStart()
{
    qDebug()<<"Controller::slotStart() 开始录制";

    if(!Global::recordStatus && !m_captureWindow->isVisible() && !m_statusBar->isVisible()){ //启动GUI
        qDebug()<<"开启GUI录制";
        CaptureRequest req(CaptureRequest::GRAPHICAL_MODE);
        uint id = req.id();
        QDBusMessage m
            = QDBusMessage::createMethodCall(QStringLiteral("org.dharkael.kylinscreencap"),
                                             QStringLiteral("/"), QLatin1String(
                                                 ""), QStringLiteral("graphicCapture"));
        QDBusConnection sessionBus = QDBusConnection::sessionBus();
        m << id;
        sessionBus.call(m);
    }else if(Global::recordStatus && m_captureWindow->isVisible() && !m_statusBar->isVisible()){ //开始录制
        qDebug()<<"开始录制 ";
        emit m_captureWindow->sigStartFromToolbar();
    }else if(Global::recordStatus && !m_captureWindow->isVisible() && m_statusBar->isVisible()){ //停止
        qDebug()<<"结束录制 ";
        m_statusBar->slotStopRecAndSave();
    }
}

void Controller::slotPause()
{
    qDebug()<<"Controller::slotPause() 暂停录制";
    if(m_statusBar->isVisible()){
        m_statusBar->slotPauseOrResumeRec();
    }
}

void Controller::slotCustom()
{
    qDebug()<<"Controller::slotCustom() 开始自定义录制";
    CaptureRequest req(CaptureRequest::GRAPHICAL_MODE);
    uint id = req.id();
    QDBusMessage m
        = QDBusMessage::createMethodCall(QStringLiteral("org.dharkael.kylinscreencap"),
                                         QStringLiteral("/"), QLatin1String(
                                             ""), QStringLiteral("graphicCapture"));
    QDBusConnection sessionBus = QDBusConnection::sessionBus();
    m << id;
    sessionBus.call(m);
}

void Controller::slotFull()
{
    qDebug()<<"Controller::slotFull() 全屏录制";
    CaptureRequest req(CaptureRequest::FULLSCREEN_MODE);
    uint id = req.id();
    QDBusMessage m
        = QDBusMessage::createMethodCall(QStringLiteral("org.dharkael.kylinscreencap"),
                                         QStringLiteral("/"), QLatin1String(
                                             ""), QStringLiteral("fullScreen"));
    QDBusConnection sessionBus = QDBusConnection::sessionBus();
    m << id;
    sessionBus.call(m);
}

void Controller::slotWin()
{
    qDebug()<<"Controller::slotWin() 窗口录制";
    int number = 1;
    CaptureRequest req(CaptureRequest::SCREEN_MODE);
    uint id = req.id();
    QDBusMessage m
        = QDBusMessage::createMethodCall(QStringLiteral("org.dharkael.kylinscreencap"),
                                         QStringLiteral("/"), QLatin1String(
                                             ""), QStringLiteral("captureScreen"));
    QDBusConnection sessionBus = QDBusConnection::sessionBus();
    m << number << id;
    sessionBus.call(m);
}

void Controller::slotOpenMic()
{
    qDebug()<<"Controller::slotOpenMic() 打开麦克风";
    if(m_statusBar->isVisible()){
        m_statusBar->slotCloseMicrophone();
    }
}

void Controller::initCameraRecorder(bool isShow, QRect cameraQRect, QRect recordingRect)
{
    if(!isShow && m_camera){                //关闭摄像头
            delete m_camera;
            m_camera = nullptr;
    }else if(isShow && !m_camera) {         //开启摄像头

        m_camera = new CameraPage(nullptr,recordingRect);

        if(cameraQRect.isEmpty() ){
            //根据录制框大小初始话摄像头
            int x = recordingRect.right() - m_camera->width() - CAMERA_TO_WINDOW_DISTANCE;
            int y = recordingRect.bottom() - m_camera->height() - CAMERA_TO_WINDOW_DISTANCE;
            m_camera->setGeometry(x,y,m_camera->width(),m_camera->height());

        }else if(!cameraQRect.isEmpty() ){
            //根据capture时的 位置大小创建摄像头
            m_camera->setGeometry(cameraQRect);
        }

        m_camera->show();
    }
}

void Controller::closeCameraRecorder()
{
    if(m_camera){
        m_camera->stopCamera();
        delete m_camera;
        m_camera = nullptr;
    }
}

void Controller::slotCameraRecordToggled(bool checked)
{
    if(m_statusBar->isVisible()){
        initCameraRecorder(checked, QRect(), m_recordingRect);
    }else if (m_captureWindow && m_captureWindow->isVisible()){
        m_captureWindow->slotUpdateCameraDisplay(checked);
    }
}

void Controller::CloseCamerafromSetting()
{
    m_settingWid->closeCamera();
}

void Controller::hideLeadWid()
{
    if(m_leadWid){
        m_leadWid->hide();
    }
}

void Controller::slotCloseRec()
{
    if (m_captureWindow)
    {
        m_captureWindow->slotShowKey(false);
        m_captureWindow->slotCloseRec();
    }
    closeCameraRecorder();
}
